package com.vgemv.jsutilitysdk.Menu.JsMenuView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshFooter;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
import com.vgemv.jsutilitysdk.JsThread.JsThreadManager;
import com.vgemv.jsutilitysdk.Menu.JsMenuFragment.JsRecyclerView;
import com.vgemv.jsutilitysdk.Menu.JsMenuView.JsMenuItemView.JsMenuItemView;
import com.vgemv.jsutilitysdk.Menu.JsMenuView.JsMenuItemVm.JsMenuItemVm;

import java.util.ArrayList;

public class JsMenuView extends FrameLayout {
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    //RecyclerView
    public JsRecyclerView mRecyclerView;

    private RecyclerView.LayoutManager mLayoutManager;


    private JsMenuViewAdapter mAdapter;

    // private ArrayList<JsMenuCellVm> mal_cells;
    private ArrayList<JsMenuItemVm> mal_vms;

    public JsMenuViewBasicCallback mBasicCallback;
    public JsMenuViewRefreshCallback mRefreshCallback;
    public JsMenuViewTouchThroughCallback mTouchThroughCallback;

    public JsMenuViewVm mMenuViewVm;

    //是否刚刚点击按下
    public boolean mb_isJustDown;

    // 当前选择itemView的index.
    private Integer mI_selectedIndex = null;

    public int mi_loadedPage = 0;

//    private JsMenuScrollView msv_root;

    public SmartRefreshLayout mll_root;

    private int setupUiCount = 0;

    public JsMenuView(Context context) {
        super(context);

        JsThreadManager.runInMainThreadAtNextRunloop(new Runnable() {
            @Override
            public void run() {
                //此时必须创建ui在这里调用.

                // 设置数据源
                if(mBasicCallback!= null) {
                    mal_vms = mBasicCallback.jsMenuViewSetDatasource();
                    mMenuViewVm = mBasicCallback.jsMenuViewSetVm(JsMenuView.this);
                    mAdapter = (JsMenuViewAdapter)mBasicCallback.jsMenuViewSetAdapter(JsMenuView.this);
                }
                if(mal_vms == null) {
                    mal_vms = new ArrayList<>();
                }
                if(mMenuViewVm == null) {
                    mMenuViewVm = new JsMenuViewVm();
                }
                if(mAdapter == null) {
                    mAdapter = new JsMenuViewDefaultAdapter();
                    mAdapter.mal_vms = mal_vms;
                    ((JsMenuViewDefaultAdapter)mAdapter).adapterCallback = new JsMenuViewAdapterCallback() {
                        @Override
                        public void jsMenuViewAdapterClickItem(JsMenuViewDefaultAdapter adapter, int index, JsMenuItemVm vm) {
                            if(mBasicCallback != null) {
                                mBasicCallback.jsMenuViewClickItem(JsMenuView.this,index,vm);
                            }
                            //首先调用回调,然后再更新index.
                            chooseItem(index);
                        }

                        @Override
                        public JsMenuItemView jsMenuViewAdpaterCreateItemView(Context context) {
                            if(mBasicCallback != null) {
                                return mBasicCallback.jsMenuViewCreateItemView(JsMenuView.this,context);
                            }
                            return null;
                        }

                        @Override
                        public void jsMenuItemViewWillDisplay(RecyclerView.ViewHolder viewHolder, int position) {
                            mBasicCallback.jsMenuItemViewWillDisplay(viewHolder,position);
                        }
                    };
                }

                setupUi();

                if(mBasicCallback != null) {
                    mBasicCallback.jsMenuViewAfterCreateView(JsMenuView.this);
                }
            }
        });
    }

    public void setupUiIfNeeded() {
        setupUiCount ++;
        if(setupUiCount == 1) {
            JsThreadManager.runInMainThreadAtNextRunloop(
                    new Runnable() {
                        @Override
                        public void run() {
                            setupUi();
                            setupUiCount = 0;
                        }
                    }
            );
        }

    }

    private void setupUi() {

        final Context context = getContext();

        {
            if(mll_root == null) {
                mll_root = new SmartRefreshLayout(getContext());
                mll_root.setId(View.generateViewId());
                //设置大小,默认大小是WRAP_CONTENT,不能设置fragment的大小,fragment没有大小的概念.只能设置fragment的rootview的大小.
                ViewGroup.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                mll_root.setLayoutParams(lp);
                setRefreshAndLoadMore(context);
                addView(mll_root);
            }



            //Recyclerview
            {
                if (mRecyclerView == null) {
                    mRecyclerView = new JsRecyclerView(getContext());
                    mRecyclerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                    mll_root.setRefreshContent(mRecyclerView);
                    //添加到View上,此时会触发onAttachToWindow上,从而设置contentView.



                    //一次手势过程中,有可能使用两个一样的数据
                    mRecyclerView.setOnTouchListener(new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View view, MotionEvent motionEvent) {
//                        JsLogManager.logc_d("onTouch","event is %d",motionEvent.hashCode());
                            if(mTouchThroughCallback != null) {
                                //存储第一下事件
                                if(!mb_isJustDown && motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
//                               JsLogManager.logc_d("onTouch","down");
                                    mb_isJustDown = true;
                                }
                                else {
                                    if(mb_isJustDown && motionEvent.getAction() == MotionEvent.ACTION_UP) {
//                                JsLogManager.logc_d("onTouch","down->up=click");
                                        //进行了一次点击
//                                mMe_first = null;
                                        return mTouchThroughCallback.jsMenuViewReceivedClickMotinEvent(motionEvent);
                                    }
                                    else {
                                        //不是点击
//                                mMe_first = null;
                                    }
                                }
                            }
                            return false;

                        }
                    });


                    // 设置布局方式 //网格布局
                    mLayoutManager = null;
                    switch (mMenuViewVm.mi_layoutStyle) {
                        case 0: {
                            GridLayoutManager layoutManager = new GridLayoutManager(getContext(), mMenuViewVm.mi_spanCount);
                            layoutManager.setOrientation(GridLayoutManager.VERTICAL);
                            mRecyclerView.setLayoutManager(layoutManager);
                            mLayoutManager = layoutManager;
                            break;
                        }
                        case 1: {
                            LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
                            layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
                            mRecyclerView.setLayoutManager(layoutManager);
                            mLayoutManager = layoutManager;
                            break;
                        }
                        case 2: {
                            //竖直线性布局.
                            LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
                            layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
                            mRecyclerView.setLayoutManager(layoutManager);
                            mLayoutManager = layoutManager;
                            break;
                        }
                        //        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(getContext(),4);
//        layoutManager.setOrientation(GridLayoutManager.VERTICAL);
//        mRecyclerView.setLayoutManager(layoutManager);
                    }



                    // 设置Item的样式

                    mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
                        @Override
                        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                            Rect rect = null;
                            int index = parent.getChildAdapterPosition(view);
                            if (mBasicCallback != null) {
                                rect = mBasicCallback.jsMenuViewSetItemOffset(JsMenuView.this, index);
                            }

                            if (rect != null) {
                                outRect.top = rect.top;
                                outRect.left = rect.left;
                                outRect.right = rect.right;
                                outRect.bottom = rect.bottom;
                            } else {
                                super.getItemOffsets(outRect, view, parent, state);
                            }
                            int recyclerViewHeight = parent.getHeight();
                            //TODO: view.getHeight,有时候为0. view.getMeasuredHeight,有时候也是0
                            // 这样就无法根据view的大小来计算相对的位置了.
                            //                int itemViewHeight = view.getHeight();
                            int itemViewHeight = view.getMeasuredHeight();
//                    JsLogManager.logc_d("JsRecyclerView", "recyclerViewHeight is %d,itemViewHeight is %d", recyclerViewHeight, itemViewHeight);
                        }
                    });


//                    if(mAdapter.getClass() == JsMenuViewDefaultAdapter.class) {
//                        ((JsMenuViewDefaultAdapter) mAdapter).adapterCallback = this;
//                    }
//                    mAdapter.mal_vms = mal_vms;

                    mRecyclerView.setAdapter(mAdapter);

                    //显示初始选择项,只在初始化时调用
                    if(mMenuViewVm.mI_initialSelectedIndex != null &&mal_vms.size() > 0) {
                        mI_selectedIndex = mMenuViewVm.mI_initialSelectedIndex;
                        JsMenuItemVm itemMenuViewVm = mal_vms.get(mI_selectedIndex);
                        itemMenuViewVm.mb_isSelected = true;
                    }
                }
            }

        }

        //背景色
        if(mMenuViewVm.mColor_background != null) {
            mRecyclerView.setBackgroundColor(mMenuViewVm.mColor_background);
        }

        //可见性
        mll_root.setVisibility(mMenuViewVm.mi_visibility);
    }


    private void setRefreshAndLoadMore (Context context) {
        //上拉刷新 下拉加载
        if (mMenuViewVm.mb_enableRefreshAndLoadmore) {
            ClassicsHeader header = new ClassicsHeader(context);
            RefreshFooter footer = new ClassicsFooter(context);
            mll_root.setRefreshHeader(header);
            mll_root.setRefreshFooter(footer);
            mll_root.setOnRefreshListener(new OnRefreshListener() {
                @Override
                public void onRefresh(RefreshLayout refreshlayout) {
                    if (mRefreshCallback != null) {
                        ClassicsHeader header = (ClassicsHeader)refreshlayout.getRefreshHeader();
                        ViewGroup.LayoutParams lp = header.getLayoutParams();
                        mRefreshCallback.onRefresh(JsMenuView.this);
                    }
                }
            });
            mll_root.setOnLoadMoreListener(new OnLoadMoreListener() {
                @Override
                public void onLoadMore(RefreshLayout refreshlayout) {
                    if (mRefreshCallback != null) {
                        mRefreshCallback.onLoadMore(JsMenuView.this, 0);
                    }
                }
            });
        } else {
            mll_root.setEnableRefresh(false);
            mll_root.setEnableLoadMore(false);
        }
    }

    public ArrayList<JsMenuItemVm> vms() {
        return mal_vms;
    }

    public Integer selectedIndex() {
        return mI_selectedIndex;
    }




    // 2 InnnerFunction


    // 3 Interface






    // 1 更新数据
    /**
     * 1.1 全部数据刷新
     * 如果mAdapter还没初始化就要求reload,其实可以不reload.
     */
    public void reloadData() {
        if(mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    /**
     * 1.2 增加数据刷新
     * @param insertedPosition      数据增加的位置.
     */
    public void  loadInsertedItem(int insertedPosition) {
        mAdapter.notifyItemInserted(insertedPosition);
    }

    /**
     * position是要减去的闭区间的前一个位置.
     * 在一个runloop中可以设置多次.
     * @param position
     * @param count
     */
    public void reloadDataRangeRemoved(int position,int count) {
        mAdapter.notifyItemRangeRemoved(position,count);
    }

    /**
     * 原来在position位置的元素,现在到position+itemcount这个位置.
     * 在指定位置position之前插入.
     * @param position
     * @param count
     */
    public void reloadDataRangeInserted(int position,int count) {
        mAdapter.notifyItemRangeInserted(position,count);
    }

    // 2 上拉加载和下拉刷新
    //
    /**
     * 结束刷新
     isSuccess
     YES:
     dataCount > 0
     * 已加载页数为1
     * 结束刷新
     * 结束下拉加载且可以加载.

     dataCount = 0
     * 已加载页数为0
     * 结束刷新
     * 结束下拉加载且不可以加载.
     * 如果有EmptyView应该显示EmptyView

     NO:仅仅结束刷新,其余状态不改变.场景是,接口获取数据失败.
     此时,上拉加载应该也是可以加载的.
     */
    public void finishRefresh(boolean isSuccess,boolean hasData) {

        if(isSuccess) {
            if(hasData) {
                //获取到了新数据数据
                mi_loadedPage = 1;
                //有可能数据已经加载完毕,但是还没有创建view.
                if(mll_root != null) {
                    mll_root.finishRefresh();
                    mll_root.finishLoadMore();
                }
            }
            else {
                mi_loadedPage = 0;
                if(mll_root != null) {
                    mll_root.finishRefresh();
                    mll_root.finishLoadMoreWithNoMoreData();
                }
            }
        }
        else {
            if(mll_root != null) {
                mll_root.finishRefresh();
                mll_root.finishLoadMore();
            }
        }
    }

    /**
     * 结束加载
     isSuccess:此次加载是否成功,如果成功
     YES:将根据dataCount设置是否还有更多的数据. 0表示没有更多数据,已加载页数不变;非0,表示还有数据,已加载页+1;
     NO:仅仅结束加载,其余状态不发生改变.
     */
    public void finishLoadMore(boolean isSuccess,boolean hasData) {
        if(isSuccess) {
            if(hasData) {
                mi_loadedPage ++;
                if(mll_root != null) {
                    mll_root.finishLoadMore();
                }
            }
            else {
                if(mll_root != null) {
                    mll_root.finishLoadMoreWithNoMoreData();
                }
            }
        }
        else {
            if(mll_root != null) {
                mll_root.finishLoadMore();
            }
        }
    }

    /**
     * 数据源改变,重新加载数据源.
     */
    public void refresh() {
        mll_root.autoRefresh();
    }


    // 3 位置控制

    /**
     * 3.1 滚动到顶部
     *
     */
    public void scrollToTop() {
        //RecyclerView does not support scrolling to an absolute position. Use scrollToPosition instead
//        mRecyclerView.scrollTo(0,0);
        mRecyclerView.scrollToPosition(0);
    }

    /**
     * scrollView滚动到最后一个元素和底部对齐.
     */
    public void scrollToBottom() {
        mRecyclerView.scrollToPosition(mal_vms.size()-1);
    }


    /**
     * 4 选择指定位置的item
     */
    public void chooseItem(int index) {
        //单选模式
        // 1 更新旧的SelectedItemView的Ui
        if(mMenuViewVm.mi_selectStyle == 1) {
            if(mI_selectedIndex != null) {
                JsMenuItemVm lastSelectedVm = mal_vms.get(mI_selectedIndex);
                lastSelectedVm.mb_isSelected = false;
                JsMenuItemView lastSelectedView = (JsMenuItemView)(mLayoutManager.findViewByPosition(mI_selectedIndex));

                /**
                 * 更新旧的的ItemView
                 * 1,如果当前itemView可见,用adapter,nofityItemChanged方法会闪一下.须要找到该view直接更新.
                 * 2,如果当前itemView不可见,findView结果为null,如果不处理,下次显示该view时,会保持旧的样式.
                 *
                 */
                if(lastSelectedView != null) {
                    lastSelectedView.setVm(lastSelectedVm);
                }
                else {

                    mAdapter.notifyItemChanged(mI_selectedIndex);
                }
            }

            //2 更新新的SelectedItemView的Ui
            JsMenuItemVm currentSelectedVm = mal_vms.get(index);
            currentSelectedVm.mb_isSelected = true;
//                adapter.notifyItemChanged(index);
            JsMenuItemView currentSelectedView = null;
            try {
                currentSelectedView = (JsMenuItemView) (mLayoutManager.findViewByPosition(index));
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            currentSelectedView.setVm(currentSelectedVm);
            mI_selectedIndex = index;
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);

        if(mMenuViewVm == null) {
            return;
        }
        int strokeWidth = mMenuViewVm.mi_borderWidth;


        if(mMenuViewVm.mi_borderWidth > 0) {
            Paint paint = new Paint();
            paint.setColor(mMenuViewVm.mColor_boerderColor);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(strokeWidth);
            int width = getMeasuredWidth();
            int height = getMeasuredHeight();
            canvas.drawRoundRect(strokeWidth / 2, strokeWidth / 2, getMeasuredWidth() - strokeWidth / 2, getMeasuredHeight() - strokeWidth / 2, mMenuViewVm.mi_cornerRadius, mMenuViewVm.mi_cornerRadius, paint);
        }
    }

    /**
     * 返回已经加载的页面数.
     * 初始为1.加载成功+1;
     */
    public int loadedPage() {
        return mi_loadedPage;
    }

    public JsMenuViewAdapter getAdapter() {
        return mAdapter;
    }
}